#include "os.h"

/*
 * 下列函数应当只在这里调用一次，
 * 因此仅在此处声明一次，不放入 os.h。
 */
extern void uart_init(void);
extern void page_init(void);

void start_kernel(void)
{
	uart_init();
	uart_puts("Hello, RVOS!\n");

	page_init();

	while (1) {}; // stop here!
}

/*
 * 文件职责说明：
 * os.h：公共头文件，声明跨文件要用的 API（UART、printf、内存管理）并引入基础类型与平台定义。
 * platform.h：平台常量/寄存器地址等硬件相关宏，各模块通过它访问 UART、内存大小等信息。
 * types.h：基础类型别名（如 uint32_t、ptr_t），保证各 C 文件使用一致的整型定义。
 * uart.c：串口驱动，实现 uart_init/uart_putc/uart_puts，供 printf 和日志输出使用。
 * printf.c：简易格式化输出库，基于 uart 提供 printf 和 panic。
 * page.c：物理页分配器，实现 page_init/page_alloc/page_free 等运行期内存管理函数。
 * kernel.c：内核主入口 (start_kernel) 的 C 代码，负责调用底层驱动和内存初始化，是后续内核逻辑的枢纽。
 * start.S：程序真正的入口 _start，在上电后最先执行，负责清 BSS、设置栈，然后跳入 start_kernel。
 * mem.S：把链接脚本 (os.ld) 定义的符号导出成全局常量（如 HEAP_START），让 C 代码能拿到段地址。
 * os.ld：链接脚本，指定各段的放置地址、内存布局，并 PROVIDE 段边界/堆起点等符号。
 * 
 * 
 * 构建与协作流程：
 * 1. 在预处理/编译阶段：kernel.c、page.c、printf.c、uart.c 这 4 个源文件在编译时各自包含.h头文件，经过预处理后再分别编译成 4 个.o目标文件；start.S, mem.S经汇编器转成2个.o目标文件。
 * 2. 在链接阶段：链接器读取各个目标文件，再根据 os.ld 确定 .text/.data/.bss 等段的内存布局，最后生成一个可执行程序。
 * 3. 在运行阶段：处理器上电后从 _start（start.S）开始执行，完成 hart 停车、清 BSS、分配栈。 然后跳转到 start_kernel（kernel.c），然后调用 uart.c、printf.c、page.c 中的函数。
 * mem.S 在运行时并没有“执行”任何代码，它只是事先把 os.ld 里定义的地址（例如 _heap_start）存成常量，供 page.c 里的 C 代码通过 extern ptr_t HEAP_START; 读取。换句话说，mem.S 作用于静态数据而不是运行期流程。
 * 
 * 注意：各文件不是层层“调用”，而是配合构建。
 */
